#ifndef HUFFMANTREE_H
#define HUFFMANTREE_H


#include <fstream>
#include <stdint.h>


//哈夫曼树中的节点
class huffmanNode
{
public:
    char data;          //该节点的8位二进制数据
    int isChosen;       //在构造哈夫曼树时该节点是否已被选择
    int isLeaf;         //该节点是否为叶子节点
    uint32_t weight;         //该节点的权重

    huffmanNode *left, *right, *next;   //左（0）右（1）分支，及构造哈夫曼树时用到的辅助指针
    huffmanNode();      //构造函数
};


//存储哈夫曼编码的类
class codeChart
{
public:
    //char code[256];
    char* code;         //编码
    int codeLen;        //codeLen为code最后一个字符的索引值，比真实长度小1
    codeChart();        //构造函数
    ~codeChart();       //析构函数
};



//哈夫曼压缩的实现和操作类
class huffmanTree
{
private:
    huffmanNode tree;               //哈夫曼树，tree.next指向哈夫曼树的顶点
    huffmanNode *leafNode;          //指向叶子节点链表
    codeChart hfmCodeChart[256];    //编码表

    char *writeBuf;                 //用来进行压缩和解压的循环队列
    int begin;                      //循环队列的起点和终点
    int end;

    uint32_t fileLen;          //原始文件的长度

    std::fstream bufOutPut;         //输出文件
    std::fstream bufReadFile;       //输入文件

public:
    huffmanTree();      //构造函数
    ~huffmanTree();     //析构函数
    int buildHuffmanTree(char* filePath);   //根据文件构造哈夫曼树
                                            //调用了weightStatics和buildTreeFromWeight

    int weightStatis(char* filePath);       //统计各数据权值
    int buildTreeFromWeight();              //由权值建立哈夫曼树

    int compress(char* oriFilePath, char* outPutFile);  //给定原始文件ori，输出压缩文件outPut
                                                        //要求哈夫曼编码已获取
    int decompress(char* compressedFile, char* outPutFile); //给定压缩文件compressed，输出原始文件outPutFile
                                                            //不要求哈夫曼树已构建
    int huffmanCompress(char* oriFile, char* outPutFile);           //
    int huffmanDecompress(char* compressedFile, char* outPutFile);  //

    int freshWeight(char buf);      //更新权值

    int printWeight();              //打印权值

    int getCodeChart();              //由哈夫曼树建立编码表
    int getCodeChartRe(char* s, int c, huffmanNode* n);  //建立编码表的递归函数writeBuf写入到文件中去

    int printCodeChart();           //打印编码表

    int writeBufToFile(char data, int isFinish = 0);    //在压缩文件时把缓冲数据

    int writeFileData();        //将压缩数据写到文件中去
    int readFileData();         //从压缩文件中读取压缩数据

};

#endif // HUFFMANTREE_H
